package com.winit.indexing.manager;

import com.winit.indexing.model.Indexing;
import com.winit.indexing.model.IndexingId;
import com.winit.indexing.repository.IIndexingRepository;
import com.winit.indexing.repository.IndexingRepositoryExt;
import com.winit.indexing.utils.IndexingUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;

@Component
public class IndexingManager {

    private static Logger log = LoggerFactory.getLogger(IndexingManager.class);

    @Autowired
    private IIndexingRepository indexingRepository;
    @Autowired
    private IndexingRepositoryExt indexingRepositoryExt;

    public void indexing(Indexing indexing) throws Exception {
        if (indexing.getId() != null && indexing.getId().isValid()) {
            Indexing existOne = this.indexingRepository.findOne(indexing.getId());
            if (null == existOne) {  //新增indexing
                if (CollectionUtils.isEmpty(indexing.getIndexMap())) {
                    log.info("empty index_map, operation indexing will be aborted, indexingId:" + indexing.getId());
                    return;
                }
                this.indexingRepository.save(indexing);
            } else {             //更新index
                Map<String, String> mergedMap = IndexingUtil.merge(existOne.getIndexMap(), indexing.getIndexMap());
                indexing.setIndexMap(mergedMap);
                this.indexingRepositoryExt.updateExistPropertyById(indexing);
            }
        } else {
            log.error("invalid indexId for indexing.");
            throw new Exception("invalid indexId for indexing.");
        }
    }

    public void remove(IndexingId indexingId, String[] referredIds) throws Exception {
        if (null == referredIds || referredIds.length == 0) {
            log.info("no referred id found for remove operation.");
            return;
        }
        if (indexingId != null && indexingId.isValid()) {
            Indexing existOne = this.indexingRepository.findOne(indexingId);
            if (null == existOne) {  //找不到
                log.error("no indexing found for indexId:" + indexingId);
                throw new Exception("no indexing found for indexId:" + indexingId);
            } else {
                Map<String, String> indexMap = existOne.getIndexMap();
                for (String referredId : referredIds) {
                    if (null == indexMap.remove(referredId)) {
                        log.error("referred id not exists for remove operation, referredId:" + referredId);
                        throw new Exception("referred id not exists for remove operation, referredId:" + referredId);
                    }
                }
                if (CollectionUtils.isEmpty(indexMap)) {     //indexMap已清空，清除该记录
                    this.indexingRepository.delete(indexingId);
                } else {
                    Indexing updateOne = new Indexing();
                    updateOne.setId(indexingId);
                    updateOne.setIndexMap(indexMap);
                    this.indexingRepositoryExt.updateExistPropertyById(updateOne);
                }

            }
        } else {
            log.error("invalid indexId for indexing.");
            throw new Exception("invalid indexId for indexing.");
        }
    }

    public void removeIfExists(IndexingId indexingId, String[] referredIds) {
        if (null == referredIds || referredIds.length == 0) {
            log.info("no referred id found for remove operation.");
            return;
        }
        if (indexingId != null && indexingId.isValid()) {
            Indexing existOne = this.indexingRepository.findOne(indexingId);
            if (null == existOne) {  //找不到
                log.info("no indexing found for indexId:" + indexingId);
                return;
            } else {
                Map<String, String> indexMap = existOne.getIndexMap();
                for (String referredId : referredIds) {
                    if (null == indexMap.remove(referredId)) {
                      log.info("no referredId removed.");
                      return;
                    }
                }
                if (CollectionUtils.isEmpty(indexMap)) {     //indexMap已清空，清除该记录
                    this.indexingRepository.delete(indexingId);
                } else {
                    Indexing updateOne = new Indexing();
                    updateOne.setId(indexingId);
                    updateOne.setIndexMap(indexMap);
                    this.indexingRepositoryExt.updateExistPropertyById(updateOne);
                }

            }
        } else {
            log.info("invalid indexId for indexing.");
        }
    }

    public Indexing getIndexing(IndexingId indexingId) {
        if (null == indexingId || (!indexingId.isValid())) {
            log.info("invalid indexId:" + indexingId);
            return null;
        }
        return this.indexingRepository.findOne(indexingId);
    }

    public List<String> getFilterTag(String indexGroup) {
        if (null == indexGroup) {
            return null;
        }
        return this.indexingRepositoryExt.findFilterTagByIndexGroup(indexGroup);
//        return null;
    }

    public List<Indexing> getFilterTagMap(String indexGroup) {
        if (null == indexGroup) {
            return null;
        }
        return this.indexingRepositoryExt.findByIndexGroup(indexGroup);
    }

    public Indexing reflushIndexing(Indexing indexing) {
        IndexingId indexingId = indexing.getId();
        if (indexingId == null || (!indexingId.isValid())) {
            return null;
        }
        Indexing rs = this.indexingRepository.findOne(indexing.getId());
        this.indexingRepository.delete(indexingId);
        this.indexingRepository.save(indexing);
        return rs;
    }


    public boolean deleteIndex(IndexingId indexingId) {
        if (indexingId.isValid()) {
            this.indexingRepository.delete(indexingId);
            return true;
        }
        return this.indexingRepositoryExt.deleteByCondition(indexingId);
    }
}
